﻿using Microsoft.Xna.Framework;
using Microsoft.Xna.Framework.Graphics;
using PloobsEngine;
using PloobsEngine.Cameras;
using PloobsEngine.Input;
using PloobsEngine.Light;
using PloobsEngine.Material;
using PloobsEngine.Modelo;
using PloobsEngine.Physics;
using PloobsEngine.Physics.Bepu;
using PloobsEngine.SceneControl;
using PloobsEngine.Utils;
using PloobsEngineDemo3;

namespace Etapa1.Screens
{
    /// <summary>
    /// Stress Test Screen
    ///THROW THE BALLS IN THE BLOCKS !!!!!!
    /// </summary>
    public class StressBepuScreen : SceneScreen
    {
        private BepuPhysicWorld physicWorld;
        private BrutalForceWorld mundo;
        private EngineStuff engine;        
        ICamera cam;

        public StressBepuScreen(EngineStuff es)
        {
            this.engine = es;
            physicWorld = new BepuPhysicWorld();
            mundo = new BrutalForceWorld(physicWorld);                                    
        }
        
        public override void LoadContent(EngineStuff es)
        {
            base.LoadContent(es);            

            InputAdvanced inp = new InputAdvanced(engine);
            engine.AddComponent(inp);

            #region Models

            ///Some Physic World Parameters
            ///No accuracy (speed up the simulation) and no gravity
            physicWorld.Space.SimulationSettings.CollisionResponse.Iterations = 1; //Essentially no sustained contacts, so don't need to worry about accuracy.
            physicWorld.Space.SimulationSettings.MotionUpdate.Gravity = Vector3.Zero;

            int numColumns = 10;
            int numRows = 10;
            int numHigh = 15;
         
            ///1500 box
            ///1500 luzes

            ///CREATE LOOOOTS OF OBJECTS AND LIGHTS
            float separation = 3;
            for (int i = 0; i < numRows; i++)
                for (int j = 0; j < numColumns; j++)
                    for (int k = 0; k < numHigh; k++)
                    {
                        SimpleModel sm = new SimpleModel("..\\Content\\Model\\block");
                        sm.SetTexture(TextureCreator.CreateColorTexture(1, StaticRandom.RandomColor()), TextureType.DIFFUSE);
                        sm.LoadModelo();
                        BoxObject pi = new BoxObject(new Vector3(separation * i, k * separation, separation * j), 1, 1,new Vector3(1));                        
                        pi.Entity.Bounciness = 1; //Superbouncy boxes help propagate shock waves.
                        pi.Entity.AngularDamping = 0f; //It looks cooler if boxes don't slowly stop spinning!                                               
                        IShader shader = new NormalDeferred();
                        shader.Initialize();
                        IMaterial mat = new Material(shader);
                        IObject obj5 = new SimpleObject(mat, pi, sm);
                        mundo.AddObject(obj5);
                        
                        ///Light is atached to the blocks
                        MoveablePointLight pl = new MoveablePointLight(pi, StaticRandom.RandomColor(), 5, 1);
                        mundo.AddLight(pl);
                        
                    }

            #endregion            

            cam = new CameraFirstPerson(true);            
            cam.FarPlane = 3000;


            ///THROW THE BALLS IN THE BLOCKS !!!!!!
            LightThrowBepu lt = new LightThrowBepu(mundo, engine);         

            #region NormalLight
            DirectionalLight ld1 = new DirectionalLight(Vector3.Left, Color.White);
            DirectionalLight ld2 = new DirectionalLight(Vector3.Right, Color.White);
            DirectionalLight ld3 = new DirectionalLight(Vector3.Backward, Color.White);
            DirectionalLight ld4 = new DirectionalLight(Vector3.Forward, Color.White);
            DirectionalLight ld5 = new DirectionalLight(Vector3.Down, Color.White);
            float li = 0.4f;
            ld1.LightIntensity = li;
            ld2.LightIntensity = li;
            ld3.LightIntensity = li;
            ld4.LightIntensity = li;
            ld5.LightIntensity = li;
            mundo.AddLight(ld1);
            mundo.AddLight(ld2);
            mundo.AddLight(ld3);
            mundo.AddLight(ld4);
            mundo.AddLight(ld5);
            #endregion

            ////Criacao de uma Tecnica
            DeferredRenderTechnic dr = new DeferredRenderTechnic(engine);
            
            IRenderTechnic[] rt = new IRenderTechnic[] { dr };
            this.RenderTechnics = rt;
            mundo.AddCamera(cam);
            this.World = mundo;
        }

    }
}

